#include "TcpConnection.h"
// #include "HttpRequest.h"
#include <stdlib.h>
#include <stdio.h>

int TcpConnection::processRead(void *arg)
{
    TcpConnection *conn = static_cast<TcpConnection *>(arg);
    // 接收数据
    HEAD head={0};
    int socket = conn->m_channel->getSocket();
    int count = conn->m_readBuf->socketRead(socket);
    if (count == 0)
    {
        //Debug("客户端断开连接");
        conn->m_evLoop->addTask(conn->m_channel, ElemType::DELETE);
    }
    // else if (count > 0)
    // {
    //    // Debug("接收到的请求数据: %s", conn->m_readBuf->data());
    //     // 这里应该进行协议的解析
    //     HEAD head = {0};
    //     char body[1024] = {0};
    //     memcpy(&head, conn->m_readBuf->data(), sizeof(HEAD));
    //     memcpy(body, conn->m_readBuf->data() + sizeof(HEAD), head.data_len);
    //     conn->m_readBuf->clear();
    //     if (head.service_type == LOGIN)
    //     {
    //         conn->task = TaskFactory::getTask(LOGIN, body, head.data_len, socket);
    //     }
    //     else if (head.service_type == CHAT)
    //     {
    //         conn->task = TaskFactory::getTask(CHAT, body, head.data_len, socket);
    //     }
    //     else if (head.service_type == FRIEND)
    //     {
    //         conn->task = TaskFactory::getTask(FRIEND, body, head.data_len, socket);
    //     }
    //     // 注册可写事件
    //     conn->task->work(conn->m_writeBuf);
    //     //conn->m_writeBuf->appendString("数据发送成功");
    //     conn->m_channel->writeEventEnable(true);
    //     conn->m_evLoop->addTask(conn->m_channel, ElemType::MODIFY);
    // }
    //--------------------------------------------------------------------------------------------

    //这边如果检测到客户端有读事件发送，那么就发送该客户端的fd给到后置服务器处理
    //直接注册写事件，这里直接往共享内存里面写入数据就行了
    else if (count > 0)
    {
        bzero(&head,sizeof(HEAD));
        memcpy(&head, conn->m_readBuf->data(), sizeof(HEAD));
        cout<<"客户端发来的请求 head.type:"<<head.service_type<<endl;
        cout<<"客户端发来的请求 head.len:"<<head.data_len<<endl;

        conn->m_channel->writeEventEnable(true);
        conn->m_evLoop->addTask(conn->m_channel, ElemType::MODIFY);
    }
}

int TcpConnection::processWrite(void *arg)
{
    //Debug("开始发送数据了(基于写事件发送)....");
    TcpConnection *conn = static_cast<TcpConnection *>(arg);
    // 发送数据
    // int count = conn->m_writeBuf->sendData(conn->m_channel->getSocket());
    // if (count > 0)
    // {
    //     // 判断数据是否被全部发送出去了
    //     if (conn->m_writeBuf->readableSize() == 0)
    //     {
    //         // 1. 不再检测写事件 -- 修改channel中保存的事件
    //         conn->m_channel->writeEventEnable(false);
    //         // 2. 修改dispatcher检测的集合 -- 添加任务节点
    //         conn->m_evLoop->addTask(conn->m_channel, ElemType::MODIFY);
    //         // 3. 删除这个节点
    //         // conn->m_evLoop->addTask(conn->m_channel, ElemType::DELETE);
    //         conn->m_writeBuf->clear();
    //     }
    // }

    char data[BLOCK_SIZE] = {0};
    int fd=conn->m_channel->getSocket();
    memcpy(data,&fd,sizeof(int));
    memcpy(data+sizeof(int),conn->m_readBuf->data(),conn->m_readBuf->readableSize());
    cout << "socket=" << conn->m_channel->getSocket() << endl;
    HEAD head={0};
    memcpy(&head,data+sizeof(int),sizeof(HEAD));
    cout<<"前端发给后端的协议类型:"<<head.service_type<<endl;
    cout << "data=" << data<<endl;
    SharedMemoryIPC&ipc=SharedMemoryIPC::getWriterInstance();

    ipc.write_shm(data);
    bzero(data, BLOCK_SIZE);
    conn->m_readBuf->clear();
    //  1. 不再检测写事件 -- 修改channel中保存的事件
    conn->m_channel->writeEventEnable(false);
    // 2. 修改dispatcher检测的集合 -- 添加任务节点
    conn->m_evLoop->addTask(conn->m_channel, ElemType::MODIFY);
    return 0;
}

int TcpConnection::destroy(void *arg)
{
    TcpConnection *conn = static_cast<TcpConnection *>(arg);
    if (conn != nullptr)
    {
        delete conn;
    }
    return 0;
}

TcpConnection::TcpConnection(int fd, EventLoop *evloop)
{
    m_evLoop = evloop;
    m_readBuf = new Buffer(10240);
    m_writeBuf = new Buffer(10240);
    // http
    // m_request = new HttpRequest;
    // m_response = new HttpResponse;
    m_name = "Connection-" + to_string(fd);
    m_channel = new Channel(fd, FDEvent::ReadEvent, processRead, processWrite, destroy, this);
    evloop->addTask(m_channel, ElemType::ADD);
    this->task = nullptr;
}

TcpConnection::~TcpConnection()
{
    if (m_readBuf && m_readBuf->readableSize() == 0 &&
        m_writeBuf && m_writeBuf->readableSize() == 0)
    {
        delete m_readBuf;
        delete m_writeBuf;
        // delete m_request;
        // delete m_response;
        m_evLoop->freeChannel(m_channel);
    }
    //Debug("连接断开, 释放资源, gameover, connName: %s", m_name);
}
